using System;
using System.Collections.Generic;
using System.Linq;

namespace DirectoryProvider
{
	public class AttributeMap
	{
		Dictionary<string,string> _dict = new Dictionary<string,string> ();

		public string this [string index] {
        
			get {
            
				string idx = index.ToLower ();
                
				if (_dict.ContainsKey (idx)) {
					return _dict [idx];
				}
            
				return index;
			}
		}
  
		internal AttributeMap Add (string key)
		{
			_dict [key.ToLower ()] = key;
			return this;
		}
        
		internal AttributeMap Add (string key, string value)
		{
			_dict [key.ToLower ()] = value;
			return this;
		}
        
		internal AttributeMap AddRange (params string[] keys)
		{
			foreach (string key in keys) {
				_dict [key.ToLower ()] = key;
			}
			return this;
		}
        
		public string[] Translate (params string[] keys)
		{
		
			string[] res = new string[keys.Length];
			for (int i=0; i<keys.Length; i++)
				res [i] = this [keys [i]];
			
			return res.Distinct ().OrderBy (x => x).ToArray ();
			
		}
		
		
		private string parsefilter (string operador, params string[] pairs)
		{
			if (pairs.Length % 2 == 1)
				throw new Exception ("Numero incorrecto de parametros");
			List<string > ret = new List<string> ();
			for (int i=0; i<pairs.Length/2; i=i+2)
				ret.Add (string.Format ("({0}={1})", this [pairs [i]], pairs [i + 1]));
			return "(" + operador + string.Join ("", ret.ToArray ()) + ")";
		
		}

		private string parsefilter (string operador, object hash)
		{
			return "(" + operador + Hash2Filter(hash) + ")";
		}
		
		public string Hash2Filter(object hash) {
			List<string > ret = new List<string> ();
			foreach (var kvp in hash.ToStringHash())
				ret.Add (string.Format ("({0}={1})", this [kvp.Key], kvp.Value [0]));
			return string.Join ("", ret.ToArray ());
		}

		#region AND
		
		public string And (object hash)
		{
			return parsefilter("&", hash);
		}

		public string And (params string[] values)
		{
			return parsefilter("&", values);
		}
		
		#endregion
		
		#region OR
		
		public string Or (object hash)
		{
			return parsefilter("|", hash);
		}

		public string Or (params string[] values)
		{
			return parsefilter("|", values);
		}
		
		#endregion
		
		#region NOT
		
		public string Not (object hash)
		{
			return parsefilter("!", hash);
		}

		public string Not (params string[] values)
		{
			return parsefilter("!", values);
		}
		
		#endregion
		
	}
}

